package com.agentframework.core.plan;

import com.agentframework.core.action.AbstractAction;
import com.agentframework.core.tools.ToolManager;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wangjun
 **/
public class WritePlanAction extends AbstractAction {

    String PROMPT_TEMPLATE = """
            # 上下文消息:
            %s
            # 可用任务工具:
            %s
            # 任务:
             根据上下文，写一个计划或修改一个现有的计划，说明你应该做些什么来实现目标。一个计划由一到 %s 个任务组成。
             如果你正在修改现有的计划，请仔细遵循说明，不要做出不必要的更改。给出整个计划，除非指示只修改计划中的一项任务。
             如果在当前任务中遇到错误，请仅修改和输出当前单个任务。
             按照以下格式输出字符串列表：
             注意：请务必按照以下示例返回JSON数据
            ```json
            [
                {
                    "task_id": str = "计划中任务的唯一标识符，可以是序号",
                    "dependent_task_ids": list[str] = "此任务的先决条件是任务的id",
                    "instruction": "在这项任务中，你应该做什么，一个简短的短语或句子",
                    "task_tools": list[str] = "你想用的工具"
                },
                ...
            ]
            ```
            """;

    public WritePlanAction(String actionName) {
        super(actionName);
    }

    @Override
    protected Prompt doExecute(List<Message> messages) {
        String tools = ToolManager.getTools().stream()
                .map(tt -> String.format("- **%s**: %s", tt.getToolDefinition().name(), tt.getToolDefinition().description()))
                .collect(Collectors.joining(System.lineSeparator()));

        String promptTemplate = String.format(PROMPT_TEMPLATE,
                messages.stream().map(Message::getText).collect(Collectors.joining("\n")),
                tools,
                3);

       return PromptTemplate.builder().template(promptTemplate).variables(new HashMap<>()).renderer((template, variables) -> template).build().create();
    }

    @Override
    protected String getFormatInstruction() {
        return PROMPT_TEMPLATE;
    }

}
